#!/usr/bin/python
# -*- coding: utf-8 -*-

import os, re
from urlparse import urlparse
from PyQt4 import QtCore, QtGui
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkProxy, QNetworkReply
from DebugLog import DebugLog, DebugFile

class QonsoExtractor(QtCore.QObject):
   def __init__(self):
      QtCore.QObject.__init__(self)
      self.urlconso = ""
      self.urlbeforeAuth = ""
      self.urlAuth = ""
      self.hostname = ""
      self.login = ""
      self.password = ""
      self.model = None
      self.view = None
      self.hmReS = ".*?((?:\s*\d{1,2}\s*[Hh])?\s*(?:\d{1,3}\s*(?:mi?n)?)).*?"
      self.hmRe = re.compile(self.hmReS)
      self.datasExtracted = False
      self.authentication = ''
      self.context = ''
      self.status = ''
      self.offline = True
      self.SetStatus('INFO', 'Connexion...')
      self.progress = 0
      self.progressRange = (0,100)
      self.datas = ''
      self.reply = None

   def SetView(self, view):
      self.view = view

   def SetLogin(self, login):
      self.login = login

   def SetPassword(self, password):
      self.password = password

   def SetOffline(self, offline):
      self.offline = offline

   def GetProgress(self):
      return self.progress

   def SetProgress(self, read, total):
      self.read = read
      self.total = total
      min, max = self.progressRange
      if total>0:
         self.progress = min+(max-min)*float(read)/float(total)
      DebugLog("QonsoExtractor::SetProgress(%f)"%self.progress)
      self.emit(QtCore.SIGNAL('progress'))

   def SetProgressRange(self, min, max):
      self.progressRange = (min, max)

   def SetStatus(self, status, context):
      #DebugLog(u"%s : %s"%(status,context))
      self.context = context
      self.status = status
      #if self.view:
      #   self.view.update()

   def GetStatus(self):
      return (self.status, self.context)

   def SetModel(self, model):
      self.model = model

   # L'authentification est en 2 passes :
   # 1. charger la page de connection pour récupérer un identifiant
   # 2. ouvrir une requête d'identification avec cet identifiant et le numéro de tél et le code
   def InitAuthenticate(self):
      DebugLog('Extractor::InitAuthenticate')
      if not self.login or not self.password:
         return
      self.authentication = 'Init'

      self.manager = QNetworkAccessManager()
      QtCore.QObject.connect(self.manager, QtCore.SIGNAL("finished(QNetworkReply *)"), self.readResponse)

      proxy = os.environ.get('PROXY')
      if proxy:
         o = urlparse(proxy)
         netlocL = o.netloc.find(':')
         host = o.netloc[:netlocL]
         DebugLog("  - Using proxy : %s://%s:%d"%(o.scheme, host, o.port))
         self.proxy = QNetworkProxy(QNetworkProxy.HttpProxy, host, o.port)
         self.manager.setProxy(self.proxy)

      DebugLog('get : %s'%self.urlbeforeAuth)
      request = QNetworkRequest()
      request.setUrl( QtCore.QUrl(self.urlbeforeAuth ) )

      self.SetProgressRange(0,10)
      self.SetProgress(10, 100)
      if self.reply:
         QtCore.QObject.disconnect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.SetProgress)
      self.reply = self.manager.get(request)
      QtCore.QObject.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.SetProgress)

   def Authenticate(self, idCorrelation):
      pass

   def readResponse(self, reply):
      DebugLog("QonsoExtractor::readResponse")

      error = reply.error()

      DebugLog(self.authentication)
      # test d'erreur, en général, pas de connection internet
      if error != QNetworkReply.NoError:
         # for l in reply.rawHeaderList():
            # print l
         # print reply.readAll()
         self.SetProgressRange(0,100)
         self.SetProgress(100, 100)
         self.SetStatus('ERROR', u"Erreur %s, vérifiez votre connection Internet"%error)

      # On est bon. On charge la page et on extrait les données
      elif self.authentication == 'Done':
         self.ExtractDatas( reply.readAll() )

      else:
         self.DoReadResponse(reply)

   def UpdateConso(self):
      DebugLog( "QonsoExtractor::UpdateConso -> set request="+self.urlconso)
      self.SetProgressRange(20,80)
      if not self.offline:
         self.authentication = 'Done'
         request = QNetworkRequest()
         request.setUrl( QtCore.QUrl(self.urlconso) )
         self.SetStatus('INFO', u'Récupération des données...')
         QtCore.QObject.disconnect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.SetProgress)
         self.reply = self.manager.get(request)
         QtCore.QObject.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.SetProgress)
      else:
         self.ExtractDatas(self.datas)

   def PrepareRequest(self):
      DebugLog( "QonsoExtractor::PrepareRequest : %s"%self.urlAuth)
      request = QNetworkRequest()
      request.setUrl( QtCore.QUrl(self.urlAuth) )
      request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
      request.setRawHeader("Connection", "keep-alive")
      request.setRawHeader("Keep-Alive", "115");
      request.setRawHeader("Referer", self.urlbeforeAuth)
      request.setRawHeader("Host", self.hostname)
      request.setRawHeader("User-Agent", "Firefox/3.5 Maemo Browser 1.7.4.8 RX-51 N900")
      return request

   def PostRequest(self, params, request=None):
      DebugLog("QonsoExtractor::PostRequest")
      DebugLog(params.toString())

      postData = QtCore.QByteArray()
      postData.append(params.toString()[1:])

      if not request:
         request = self.PrepareRequest()

      request.setRawHeader("Content-Length", "%s" % postData.length() )
      DebugLog("post request")
      QtCore.QObject.disconnect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.SetProgress)
      self.reply = self.manager.post(request, postData)
      QtCore.QObject.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.SetProgress)

   def ExtractDatas(self, datas):
      DebugLog("QonsoExtractor::ExtractDatas")

      if self.offline:
         self.datas = datas

      self.SetProgressRange(80,100)
      DebugLog('Extraction des données')
      self.SetStatus('INFO', u'Extraction des données...')

      #DebugFile(datas)
      self.DoExtractDatas( str(datas) )
      self.datasExtracted = True
      self.SetProgress(100, 100)

      DebugLog('----------------------------------------------\nQonsoExtractor::ExtractDatas done')
      if self.status != 'ERROR':
         self.SetStatus('DONE', u'Terminé')

      if self.view:
         DebugLog("QonsoExtractor:: update view")
         self.emit(QtCore.SIGNAL('extracted'))

      if self.model.NotFilled() and self.status!='ERROR' and not self.offline:
         DebugLog("QonsoExtractor:: Model not filled! UpdateConso")
         #self.UpdateConso()

   def DoReadResponse(self, reply):
      pass

   def DoExtractDatas(self, datas):
      pass
